import static org.junit.Assert.*;

import java.util.Random;

import org.junit.Test;

public class TestIsValid {
	private static int MAXRUNS = 10000;

	@Test
	public void testIsValid() {
		int runs = 0;
		ResultPair[] fragments;
		String url;
		boolean expectedValue, actualValue, fragActual;
		UrlValidator validator = new UrlValidator(UrlValidator.ALLOW_ALL_SCHEMES +
				UrlValidator.ALLOW_2_SLASHES);

		while (runs < MAXRUNS) {

			// get random fragment combination
			fragments = getFrags();

			// build URL, calculate expected result
			url = "";
			expectedValue = true;
			for (int i = 0; i < 5; i++) {
				url += fragments[i].item;
				expectedValue &= fragments[i].valid;
			}

			// compare actual against isValid()
			actualValue = validator.isValid(url);

			if (expectedValue != actualValue) {
				System.out.println("<-- Fail -->");
				System.out.printf("Url\t\texpected: %s, actual: %s, string: '%s'\n",
						expectedValue, actualValue, url);				
				System.out.printf("Scheme:\t\texpected: %s, string:  '%s'\n", fragments[0].valid, fragments[0].item);
				System.out.printf("Authority:\texpected: %s, string:  '%s'\n", fragments[1].valid, fragments[1].item);
				System.out.printf("Port:\t\texpected: %s, string:  '%s'\n", fragments[2].valid, fragments[2].item);
				System.out.printf("Path:\t\texpected: %s, string:  '%s'\n", fragments[3].valid, fragments[3].item);
				System.out.printf("Query:\t\texpected: %s, string:  '%s'\n", fragments[4].valid, fragments[4].item);
			}
			assertEquals(expectedValue, actualValue);
			runs++;
		}
	}

	// return array of random fragment combos
	public ResultPair[] getFrags() {
		ResultPair[] fragCombo = new ResultPair[5];
		Random rand = new Random();

		fragCombo[0] = testUrlScheme[rand.nextInt(testUrlScheme.length)];
		fragCombo[1] = testUrlAuthority[rand.nextInt(testUrlAuthority.length)];
		fragCombo[2] = testUrlPort[rand.nextInt(testUrlPort.length)];
		fragCombo[3] = testPath[rand.nextInt(testPath.length)];
		fragCombo[4] = testUrlQuery[rand.nextInt(testUrlQuery.length)];
		return fragCombo;
	}

	public static void main(String argv[]) {
		TestIsValid uvt = new TestIsValid();
		uvt.testIsValid();
	}


	ResultPair[] testUrlScheme = { new ResultPair("http://", true),
			new ResultPair("ftp://", true), new ResultPair("h3t://", true),
			new ResultPair("3ht://", false), new ResultPair("http:/", false),
			new ResultPair("http:", false), new ResultPair("http/", false),
			new ResultPair("://", false)}; //, new ResultPair("", true) 

	ResultPair[] testUrlAuthority = { new ResultPair("www.google.com", true),
			new ResultPair("go.com", true), new ResultPair("go.au", true),
			new ResultPair("0.0.0.0", true),
			new ResultPair("255.255.255.255", true),
			new ResultPair("256.256.256.256", false),
			new ResultPair("255.com", true),
			new ResultPair("1.2.3.4.5", false),
			new ResultPair("1.2.3.4.", false), new ResultPair("1.2.3", false),
			new ResultPair(".1.2.3.4", false), new ResultPair("go.a", false),
			new ResultPair("go.cc", true), //new ResultPair("go.a1a", false), 
			new ResultPair("go.1aa", false), new ResultPair("aaa.", false),
			new ResultPair(".aaa", false), new ResultPair("aaa", false),
			new ResultPair("", false) };

	ResultPair[] testUrlPort = { new ResultPair(":80", true),
			new ResultPair(":65535", true), new ResultPair(":0", true),
			new ResultPair(":-1", false), //new ResultPair("", true), 
			new ResultPair(":65636", true), new ResultPair(":65a", false) };

	ResultPair[] testPath = { new ResultPair("/test1", true),
			new ResultPair("/t123", true), new ResultPair("/$23", true),
			new ResultPair("/..", false), new ResultPair("/../", false),
			new ResultPair("/test1/", true), // new ResultPair("", true),
			new ResultPair("/test1/file", true),
			new ResultPair("/..//file", false) };  //, new ResultPair("/test1//file", false)

	ResultPair[] testUrlQuery = { new ResultPair("?action=view", true),
			new ResultPair("?action=edit&mode=up", true),
			new ResultPair("", true) };



}

